import { effect, ReactiveEffectOptions, ReactiveEffectRunner, stop } from "@vue/reactivity";
import { _decorator, Component, error, tween, Vec3,Node } from "cc";
import { UIViewFieldPath } from "./UIViewFieldPath";
import { SearchType } from "./UIDecorator";

// View.ts
const { ccclass, property } = _decorator;

@ccclass("BaseView")
export default class BaseView extends Component {

    
    // 默认动画时长
    private static DEFAULT_ANIM_DURATION: number = 0.3;

    // 是否已初始化
    private _isInitialized: boolean = false;
    private effectsRefs:ReactiveEffectRunner[] = []
    protected animationShowFunc:()=>void = null;
    protected animationCloseFunc:()=>void = null;
    protected useAnimation = true

    public get viewName(){
        return this.node.name
    }

    // 生命周期：初始化（第一次显示时调用）
    protected init() {
        // 子类重写
    }

    // 生命周期：显示（每次显示时调用）
    protected show(...args: any[]) {
        // 子类重写
    }

    // 生命周期：关闭（隐藏时调用）
    protected close() {
        // 子类重写
    }


    protected addEffect<T = any>(fn: () => T, options?: ReactiveEffectOptions){
        this.effectsRefs.push(effect(fn,options))
    }

    // 显示UI（带默认动画）
    public async showView(...args: any[]) {
        if (!this._isInitialized) {
            this._isInitialized = true;
            this.nodeBindHandle();
            this.init();
        }
        this.node.active = true;
        this.show(...args);
        if(this.useAnimation){
            await this.playShowAnimation();
        }
    }
    nodeBindHandle() {
        let clazzNmae = this.constructor.name
        for (const key in this) {
            let keyPath = clazzNmae+"_"+key
            if(UIViewFieldPath.bindMetas.has(keyPath)){
                let meta = UIViewFieldPath.bindMetas.get(keyPath)
                //查找节点
                if(meta.type==null){
                    let found = this.node.getChildByPath(meta.path)
                    if(found){
                        this[key] = found as any
                        continue
                    }else{
                        throw new error(clazzNmae+" not found node in path"+meta.path)
                        break
                    }
                }
                //找组件
                if(meta.searchType==SearchType.Single){
                    let found = this.node.getChildByPath(meta.path)
                    if(found){
                        let comp = found.getComponent(meta.type)
                        if(comp){
                            this[key] = comp
                        }else{
                            throw new error(clazzNmae+" not found component in path"+meta.path+" type:"+meta.type.name)
                        }

                    }else{
                        throw new error(clazzNmae+" not found node in path"+meta.path)
                    }
                    continue
                }
                if(meta.searchType==SearchType.Children){
                    let result = []
                    let children = []
                    if(meta.path===""){
                        children = this.node.children
                    }else{
                        let found = this.node.getChildByPath(meta.path)
                        if(found){
                            children = found.children
                        }else{
                            throw new error(clazzNmae+" not found node in path"+meta.path)
                        }
                    }
                    children.forEach(n=>{
                        let cmp = n.getComponent(meta.type)
                        if(cmp){
                            result.push(cmp)
                        }
                    })
                    this[key] = result as any
                    continue
                }
                // if(meta.searchType==SearchType.Descendants){
                //     let found = this.node.getChildByPath(meta.path)
                //     let result = []
                //     if(found){
                //         found.getComponents(meta.type)
                //         found.children.forEach(n=>{
                //             let cmp = n.getComponent(meta.type)
                //             if(cmp){
                //                 result.push(cmp)
                //             }
                //         })
                //         this[key] = result as any
                //     }else{
                //         throw new error(clazzNmae+" not found node in path"+meta.path)
                //     }
                //     return
                // }
            }
        }
    }



    // 隐藏UI（带默认动画）
    public async closeView() {
        if(this.useAnimation){
            await this.playCloseAnimation();
        }
        this.node.active = false;
        this.effectsRefs.forEach(e=>stop(e))
        this.effectsRefs = []
        this.close();
    }

    // 播放显示动画
    private async playShowAnimation(): Promise<void> {
        if(this.animationShowFunc){
            return this.animationShowFunc?.()
        }
        this.node.setScale(new Vec3(0, 0, 1)) ;
        return new Promise((resolve) => {
            tween(this.node)
                .to(BaseView.DEFAULT_ANIM_DURATION, { scale: new Vec3(1,1,1) }, { easing: "linear" })
                .start();
        });
    }

    // 播放关闭动画
    private async playCloseAnimation(): Promise<void> {
        if(this.animationCloseFunc){
            return this.animationCloseFunc?.()
        }
        return new Promise((resolve) => {
            tween(this.node)
                .to(BaseView.DEFAULT_ANIM_DURATION, { scale: new Vec3(0,0,0) }, { easing: "linear" })
                .start();
        });
    }
}